package com.greenbook.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.greenbook.constant.MessageConstant;
import com.greenbook.dto.UserInfoDTO;
import com.greenbook.dto.UserLoginDTO;
import com.greenbook.entity.UserAuth;
import com.greenbook.entity.UserInfo;
import com.greenbook.entity.UserStatistics;
import com.greenbook.exception.AccountNotFoundException;
import com.greenbook.exception.LoginTypeException;
import com.greenbook.exception.PasswordErrorException;
import com.greenbook.mapper.UserAuthMapper;
import com.greenbook.mapper.UserInfoMapper;
import com.greenbook.mapper.UserStatisticsMapper;
import com.greenbook.properties.JwtProperties;
import com.greenbook.service.UserService;
import com.greenbook.utils.JwtUtil;
import com.greenbook.vo.UserInfoVO;
import com.greenbook.vo.UserLoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {

    private final UserAuthMapper userAuthMapper;
    private final UserInfoMapper userInfoMapper;
    private final UserStatisticsMapper userStatisticsMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtProperties jwtProperties;

    /**
     * 用户登录
     *
     * @param userLoginDTO 用户登录信息
     * @return 用户登录信息
     */
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        // 1. 选择登录逻辑
        switch (userLoginDTO.getLoginType()) {
            // 密码登录方式
            case 1:
                return passwordLogin(userLoginDTO);
            case 2:
                log.info("手机验证码登录");
                break;
            case 3:
                log.info("邮箱验证码登录");
                break;
            case 4:
                log.info("第三方登录");
                break;
            default:
                throw new LoginTypeException("不支持的登陆类型");
        }
        return null;
    }

    /**
     * 密码登录
     * @param userLoginDTO
     * @return
     */
    public UserLoginVO passwordLogin(UserLoginDTO userLoginDTO){
        String loginName = userLoginDTO.getLoginName(); // loginName 可能是用户名，也可能是手机号
        String password = userLoginDTO.getPassword();

        //1. 根据用户名或手机号查询用户信息
        LambdaQueryWrapper<UserAuth> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserAuth::getUsername, loginName)
                .or()
                .eq(UserAuth::getPhone, loginName)
                .or()
                .eq(UserAuth::getEmail, loginName);
        UserAuth userAuth = userAuthMapper.selectOne(queryWrapper);
        // 2. 处理各种异常
        if (userAuth == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 3.密码校验(Bcrypt加密)
        if (!passwordEncoder.matches(password, userAuth.getPassword())) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
        // 4. 登录成功，生成JWT令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userAuth.getId());
        String token = JwtUtil.createToken(jwtProperties, claims);
        // 5. 查询用户信息
        LambdaQueryWrapper<UserInfo> userInfoQueryWrapper = new LambdaQueryWrapper<>();
        userInfoQueryWrapper.eq(UserInfo::getUserId, userAuth.getId());
        UserInfo userInfo = userInfoMapper.selectOne(userInfoQueryWrapper);

        // 6. 封装返回结果
        return UserLoginVO.builder()
                .userId(userInfo.getUserId())
                .avatar(userInfo.getAvatar())
                .token(token)
                .build();
    }

    /**
     * 获取用户信息
     * @return
     */
    @Override
    public UserInfoVO getUserInfo(Long userId) {
        // 1. 根据用户id查询用户认证信息
        LambdaQueryWrapper<UserAuth> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(UserAuth::getId, userId);
        UserAuth userAuth = userAuthMapper.selectOne(queryWrapper1);
        // 2. 根据用户id查询用户信息
        LambdaQueryWrapper<UserInfo> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(UserInfo::getUserId, userId);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper2);

        // 3. 查询用户统计信息
        LambdaQueryWrapper<UserStatistics> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.eq(UserStatistics::getUserId, userId);
        UserStatistics userStatistics = userStatisticsMapper.selectOne(queryWrapper3);

        UserInfoVO userInfoVO = new UserInfoVO();

        // 4. 拷贝用户信息
        if (userAuth != null && userInfo != null) {
            BeanUtils.copyProperties(userInfo, userInfoVO);
            BeanUtils.copyProperties(userAuth, userInfoVO);
            BeanUtils.copyProperties(userStatistics, userInfoVO);
            userInfoVO.setLikedAndCollectedCount(userStatistics.getCollectedCount() + userStatistics.getLikedCount());
        }
        return userInfoVO;
    }

    /**
     * 更新用户信息
     * @param userInfoDTO
     */
    @Override
    public void updateUserInfo(UserInfoDTO userInfoDTO) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUserId, userInfoDTO.getUserId());
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        userInfo.setNickname(userInfoDTO.getNickname());
        userInfo.setAvatar(userInfoDTO.getAvatar());
        userInfo.setDescription(userInfoDTO.getDescription());
        userInfoMapper.updateById(userInfo);
    }
}

